package com.Wheesper.www.WheesperServer.Model;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

import com.wheesper.www.WheesperServer.Utils.Logger;


public class GroupCenter {
	private static GroupCenter _instance = new GroupCenter();
	public static GroupCenter Instance() {
		return _instance;
	}
	
	//保存每个用户所加入的群组
	private Map<String,Set<Group>> _user2groups;
	//映射：创建者 -> 其创建的群
	private Map<String,Set<Group>> _creator2groups;
	private Map<Integer,Group> _id2groups;
	private Set<Group> _allgroups;
	private GroupCenter() {
		this._user2groups = new HashMap<String,Set<Group>>();
		this._creator2groups = new HashMap<String,Set<Group>>();
		this._id2groups = new HashMap<Integer,Group>();
		this._allgroups = new TreeSet<Group>();
	}
	
	//helper func
	private void userMapGroup(String user_email,Group group,Map<String,Set<Group>> maps) {
		Set<Group> groups_set = maps.get(user_email);
		if(groups_set != null) {
			groups_set.add(group);
		}else {
			groups_set = new TreeSet<Group>();
			groups_set.add(group);
			maps.put(user_email, groups_set);
		}
	}
	
	//用于创建一个新群
	public Group createGroup(String creator_email,String groupName,String groupIntro) {
		Group group = GroupFactory.Instance().createGroup(creator_email);
		UserInfo user_info = UserInfoCenter.Instance().UserInfo(creator_email);
		String nickname = user_info.NickName();
		group.addNewMember(creator_email, nickname);
		group.Name(groupName);
		group.Intro(groupIntro);
		
		//Logging 
		Logger.Instance().logging("[User Creating a Group]{\n"
				+ "User:" + creator_email +"\n"
				+ "GroupID:" + group.ID() +"\n"
				+ "GroupName:" + group.Name() + "\n"
				+  "GroupIntro:" + group.Intro()+"\n"
				+ "}");
		
		userMapGroup(creator_email,group,this._user2groups);
		userMapGroup(creator_email,group,this._creator2groups);
		this._id2groups.put(group.ID(), group);
		this._allgroups.add(group);
		return group;
	}
	
	//用于加入一个新群
	public void userParticipateInGroup(String user_email,Integer group_id) {
		UserInfo user_info = UserInfoCenter.Instance().UserInfo(user_email);
		String nickname = user_info.NickName();
		Group group = _id2groups.get(group_id);
		group.addNewMember(user_email, nickname);
		Logger.Instance().logging("[User Participated in a Group]{\n"
				+ "User:" + user_email +"\n"
				+ "GroupID:" + group.ID() +"\n"
				+ "GroupName:" + group.Name() + "\n"
				+  "GroupIntro:" + group.Intro()+"\n"
				+ "}");
		userMapGroup(user_email,group,this._user2groups);
	}
	
	public Set<Group> getGroupsBy(String user_email){
		return this._user2groups.get(user_email);
	}
	
	public Set<Group> getGroupsBy(User user){
		String email = user.eMail();
		return getGroupsBy(email);
	}
	
	public Set<Group> getGroupCreatedBy(String email){
		return this._creator2groups.get(email);
	}
	
	public Set<Group> getGroupCreatedBy(User user){
		return getGroupCreatedBy(user.eMail());
	}
	
	//输入群名字，然后返回相同名字的群。
	public Set<Group> searchGroupByName(String group_name){
		Set<Group> groups_with_same_name = new TreeSet<Group>();
		_allgroups.forEach(new Consumer<Group>() {
			@Override
			public void accept(Group t) {
				if(group_name.contentEquals(t.Name()))
					groups_with_same_name.add(t);
			}
		});
		return groups_with_same_name;
	}
	
	//通过群ID来查找群，如果找不到，则返回null
	public Group searchGroupByID(Integer group_id) {
		Group group = null;
		Iterator<Group> iter = _allgroups.iterator();
		while(iter.hasNext()) {
			if((group = iter.next()).ID() == group_id)
				return group;
		}
		return null;
	}
}

class GroupFactory {
	private AtomicInteger groupIdCounter;
	private static GroupFactory _factory = new GroupFactory();
	private GroupFactory() {
		groupIdCounter = new AtomicInteger(0);
	}
	
	public static GroupFactory Instance() {
		return _factory;
	}
	
	// Create a unique Group for the Client 
	public Group createGroup(String creator_email) {
		Integer id = groupIdCounter.incrementAndGet();
		return new Group(id,creator_email);
	}
}

